package org.jasig.cas.ext.pac4j.web.flow;

import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.ext.util.Constants;
import org.jasig.cas.support.pac4j.authentication.principal.ClientCredential;
import org.jasig.cas.web.support.WebUtils;
import org.pac4j.core.client.BaseClient;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.context.J2EContext;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.credentials.Credentials;
import org.pac4j.core.exception.RequiresHttpAction;
import org.pac4j.core.profile.CommonProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.webflow.action.AbstractAction;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;

/**
 * Created by rain.wen on 2016/9/3.
 */
public abstract class OAuthBindAction extends AbstractAction {

    /**
     * OAuth 配置
     */
    @NotNull
    protected Clients clients;

    protected final static Logger logger = LoggerFactory.getLogger(OAuthBindAction.class);

    /**
     * 返回 OAuth 配置
     *
     * @return OAuth 配置
     */
    public Clients getClients() {
        return clients;
    }

    /**
     * 设置 OAuth 配置
     *
     * @param clients
     *        OAuth 配置
     */
    public void setClients(Clients clients) {
        this.clients = clients;
    }


    /**
     * @param context
     *        请求上下文
     */
    @Override
    protected Event doExecute(RequestContext context) throws Exception {
        final HttpServletRequest request = WebUtils.getHttpServletRequest(context);
        final HttpServletResponse response = WebUtils.getHttpServletResponse(context);

        // web context
        final WebContext webContext = new J2EContext(request, response);

        // get provider type
        final String clientName = request.getParameter(this.clients.getClientNameParameter());
        logger.debug("clientName : {}", clientName);

        // it's an authentication
        if (StringUtils.isNotBlank(clientName) == true) {
            // get client
            final BaseClient<Credentials, CommonProfile> client =
                    (BaseClient<Credentials, CommonProfile>) this.clients
                            .findClient(clientName);
            logger.debug("client : {}", client);

            //从Spring flow 中取出用户信息
            final ClientCredential clientCredential  = (ClientCredential) context.getFlowScope().get(Constants.OAUTH_CREDENTIALS);

            if (bind(request, client, clientCredential) == true) {
                return success();
            }
        }

        return error();
    }

    /**
     * 验证 OAuth 用户是否已站内绑定
     * @param client
     * @param credentials
     * @return
     */
    protected abstract boolean bind(final HttpServletRequest request, final Client client,
                                    final ClientCredential credentials);
}
